package com.ruoyi.common.utils.wx;

import com.ruoyi.common.utils.EmptyUtils;
import com.ruoyi.common.utils.MyX509TrustManager;
import com.ruoyi.common.utils.RedisUtil;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

@Component
public class WxAccessTokenUtils {
    @Resource
    private WXPayConfig wxPayConfig;
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    /**
     * 获取微信ticket<BR>
     *
     * @author yuexl
     * @param token
     * @return
     * @version 1.0
     */
    public static String getTicket(String token) {
        if ("".equalsIgnoreCase(token) || null == token) {
            return "";
        }
        String ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi";
        JSONObject result = httpRequest(ticket_url, "POST",null);
        return result.get("ticket").toString();

    }

    /**
     * 获取access_token
     *
     * @param appid
     *            凭证
     * @param appsecret
     *            密钥
     * @return
     */
    public static WxAccessToken getAccessToken(String appid, String appsecret) {
        WxAccessToken accessToken = null;

        String requestUrl = token_url.replace("APPID", appid).replace(
                "APPSECRET", appsecret);
        // 发送GET请求获取凭证
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        // 如果请求成功
        if (null != jsonObject) {
            //try {
            if(EmptyUtils.isNotEmpty(jsonObject.get("errcode"))){
                System.out.println(jsonObject.get("errmsg"));
                return null;
            }
            accessToken = new WxAccessToken();
            accessToken.setAccessToken(jsonObject.getString("access_token"));
            long tokenTime = Long.valueOf(jsonObject.getString("expires_in"));
            long time = System.currentTimeMillis();
            time = time + tokenTime * 1000;
            accessToken.setTokenLoseTime(String.valueOf(time));
        }
        return accessToken;
    }

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl
     *            请求地址
     * @param requestMethod
     *            请求方式（GET、POST）
     * @param outputStr
     *            提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpRequest(String requestUrl,
                                         String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
                    .openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect();


            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(
                    inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(
                    inputStreamReader);

            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }


    /**
     * 获取微信公众号的accessToken
     * @param appIdWx
     * @param appSecretWx
     * @param redisUtil
     * @return
     */
    public WxAccessToken getWxAccessTokenOfRepair(String appIdWx, String appSecretWx, RedisUtil redisUtil) {
        WxAccessToken wxAccessToken = (WxAccessToken)redisUtil.get("wxAccessToken");
        if(EmptyUtils.isEmpty(wxAccessToken)){
            wxAccessToken =   getAccessToken(appIdWx, appSecretWx);
            try {
                if(EmptyUtils.isNotEmpty(wxAccessToken)){
                    redisUtil.set("wxAccessToken", wxAccessToken, 7200);
                    return  wxAccessToken;
                }else{
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }else{
            String lostTime = wxAccessToken.getTokenLoseTime();
            if(System.currentTimeMillis() > Long.valueOf(lostTime)){
                wxAccessToken = getAccessToken(appIdWx, appSecretWx);
                if(EmptyUtils.isNotEmpty(wxAccessToken)){
                    try {
                        redisUtil.set("wxAccessToken", wxAccessToken, 7200);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }else{
                JSONObject jsonObject = httpRequest("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token="+wxAccessToken.getAccessToken(), "GET", null);
                if(!jsonObject.has("ip_list")){
                    wxAccessToken = getAccessToken(appIdWx, appSecretWx);
                    if(EmptyUtils.isNotEmpty(wxAccessToken)){
                        wxAccessToken.setId("3");
                        try {
                            redisUtil.set("wxAccessToken", wxAccessToken, 7200);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return  wxAccessToken;
        }
    }

}
